package com.tegistuff.webos.run.debugger.infrastructure;

import com.intellij.xdebugger.frame.*;
import com.intellij.xdebugger.ui.DebuggerIcons;
import com.tegistuff.webos.run.debugger.WebOSDebugProcess;
import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import javax.swing.*;

/**
 * WebOSVar.java
 *
 * Copyright (C) 2011-2012 Timo Tegtmeier.
 * All rights reserved.
 */
public class WebOSVar extends XValue {

    private WebOSDebugProcess myDebugProcess;
    private JSONObject myVariable;
    private boolean myHaveChildren;
    private XValueChildrenList myValues;

    public WebOSVar(WebOSDebugProcess debugProcess, JSONObject variable) throws JSONException {
        myDebugProcess = debugProcess;
        myVariable = myDebugProcess.getVariableRepository().resolve(variable);
    }

    @Override
    public void computePresentation(@NotNull XValueNode node, @NotNull XValuePlace place) {
        WebOSDebuggerVarRepository varRepository = myDebugProcess.getVariableRepository();
        WebOSDebuggerVarRepository.JSONVarType type = varRepository.getType(myVariable);
        String value = varRepository.getAsString(myVariable, type);
        Icon valueIcon = getValueIcon(type);
        myHaveChildren = getHaveChildren(type);
        node.setPresentation(valueIcon, type.toString(), value, myHaveChildren);
    }

    @Override
    public void computeChildren(@NotNull XCompositeNode node) {
        if(!myHaveChildren) {
            super.computeChildren(node);
        } else {
            if(myValues == null) {
                myValues = new XValueChildrenList();
                addChildren();
            }
            node.addChildren(myValues, true);
        }
    }

    private Icon getValueIcon(WebOSDebuggerVarRepository.JSONVarType type) {
        switch(type) {
            case Object:
                return DebuggerIcons.VALUE_ICON;
            case Array:
                return DebuggerIcons.ARRAY_VALUE_ICON;
        }
        return DebuggerIcons.PRIMITIVE_VALUE_ICON;
    }

    private boolean getHaveChildren(WebOSDebuggerVarRepository.JSONVarType type) {
        if(type != WebOSDebuggerVarRepository.JSONVarType.Object &&
           type != WebOSDebuggerVarRepository.JSONVarType.Array)
            return false;

        try {
            JSONArray properties = myVariable.getJSONArray(WebOSDebuggerConstants.V8_PROPERTIES);
            return properties.length() > 0;
        } catch(JSONException e) {
            myDebugProcess.reportInternalError(e);
            return false;
        }
    }

    private void addChildren() {
        try {
            JSONArray properties = myVariable.getJSONArray(WebOSDebuggerConstants.V8_PROPERTIES);
            for(int i = 0; i < properties.length(); i++) {
                JSONObject variable = properties.getJSONObject(i);
                String name = variable.getString(WebOSDebuggerConstants.V8_NAME);
                if(isHidden(name))
                    continue;
                myValues.add(name, new WebOSVar(myDebugProcess, variable));
            }
        } catch(JSONException e) {
            myDebugProcess.reportInternalError(e);
        }
    }
    
    public static boolean isHidden(String name) {
        return name.startsWith(WebOSDebuggerConstants.V8_HIDDEN_PREFIX);
    }
}
